package cmd

import (
    "errors"
    "fmt"
    "os"
    "path/filepath"
    "strings"

    "gitee.com/exi-red/maketools/util"
    "github.com/otiai10/copy"
    "github.com/spf13/cobra"
)

const (
    // Cp 子命令
    Cp = "cp"

    // CpDesc 描述
    CpDesc = "复制资源文件到指定目录"
)

// CpFlags cp 子命令参数结构
type CpFlags struct {
    Sources Params // 要拷贝的目录
    Target  Params // 目标目录
}

// CpFlag cp 子命令参数
var CpFlag = CpFlags{
    Sources: Params{
        Name:      "sources",
        Shorthand: "s",
        Value:     "",
        Usage:     "要拷贝的目录或文件（支持多个），半角逗号分隔",
    },
    Target: Params{
        Name:      "target",
        Shorthand: "t",
        Value:     "",
        Usage:     "目标目录",
    },
}

// 注册子命令 Cp
var cpCmd = &cobra.Command{
    Use:   Cp,
    Short: CpDesc,
    Long:  util.CLIHeader(40, CpDesc),
    Example: strings.NewReplacer(
        "{ROOTNAME}", ROOTNAME,
        "{cp}", Cp,
        "{Sources}", CpFlag.Sources.Name,
        "{Target}", CpFlag.Target.Name,
    ).Replace(
        `  {ROOTNAME} {cp} ^ 
    --{Sources} "./dir,/path/to/dir,..." ^ 
    --{Target}  "./dir|/path/to/dir" `,
    ),
    Run: func(cmd *cobra.Command, args []string) {
        // 处理器执行
        err := cpHanlder(cmd)
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
    },
}

// 初始化
func init() {
    // 禁用自动排序
    cpCmd.Flags().SortFlags = false

    // 解析参数
    StringP(cpCmd, CpFlag.Sources)
    StringP(cpCmd, CpFlag.Target)

    // 自定义帮助信息
    BoolP(cpCmd, "help", "h", false, "显示 cp 命令的帮助")
}

// 复制资源处理器
func cpHanlder(cmd *cobra.Command) error {
    flags := cmd.Flags()

    // 源目录
    source, _ := flags.GetString(CpFlag.Sources.Name)
    if source == "" {
        return errors.New("source directory not specified")
    }

    // 目标目录
    target, _ := flags.GetString(CpFlag.Target.Name)
    if target == "" {
        return errors.New("target directory not specified")
    }

    // 解析源目录
    sources := strings.Split(source, ",")
    sourcesPath := make([]string, 0)
    for _, source := range sources {
        source = util.PathFormat(source)

        // 路径不存在
        _, err := os.Stat(source)
        if os.IsNotExist(err) {
            continue
        }
        if source != "" {
            sourcesPath = append(sourcesPath, source)
        }
    }

    // 解析目标目录
    target = util.PathFormat(target)
    for _, src := range sources {
        // 在目标目录下创建与源目录同名的子目录
        dst := filepath.Join(target, filepath.Base(src))
        err := copy.Copy(src, dst)
        if err != nil {
            return err
        }
    }
    return nil
}
